package com.xlh.controller.courseTest;

import com.google.common.collect.Lists;
import com.xlh.common.Result;
import com.xlh.dto.PageDTO;
import com.xlh.dto.course.ChapterBasicInfoDTO;
import com.xlh.dto.course.ZtreeDTO;
import com.xlh.dto.courseTest.QuestionListDTO;
import com.xlh.dto.courseTest.QuestionRepositoryDropdownListDTO;
import com.xlh.dto.courseTest.TypeQuestionListDTO;
import com.xlh.param.courseTest.IdsParam;
import com.xlh.param.courseTest.QuestionRepositoryAddQuestionParam;
import com.xlh.param.courseTest.QuestionRepositoryUpdateQuestionParam;
import com.xlh.service.courseTest.RepositoryImportService;
import com.xlh.service.courseTest.RepositoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;

/**
 * @author zhr 2019/1/30 题库操作相关controller层，包含的功能有
 * 1. 获取题目类型和章节的下拉列表
 * 2. 展示当前教师可以编辑的试题
 * 3. 添加试题：如果是管理员用户添加，则为预置题目；如果是教师添加，则为非预置题目
 * 4. 从预置题库导入试题
 * 5. EXCEL导入试题
 * 6. 批量删除试题
 * 7. 修改试题
 * 8. 实验题的特别设置：实验题的镜像分配（从前端调用王晨的请求）、实验报告查重设置（放在修改试题中）等
 * 9. 下载EXCEL导入试题模板
 * 10.（无分页）查询预置题库
 * 11.需要一个定时任务策略，能够回收题库详情从表的脏数据
 * 12.（无分页）按照题型列出题目
 */
@RestController
@Api(tags = "QuestionRepository", description = "题库接口")
@RequestMapping("/course/{courseId}/businessType/{businessType}/question-repository")
public class QuestionRepositoryController {

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RepositoryImportService repositoryImportService;

    @ApiOperation("获取试卷下拉列表")
    @GetMapping(value = "/dropdown-list")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result<QuestionRepositoryDropdownListDTO> dropdownList(
            @PathVariable(value = "courseId") Long courseId, @PathVariable("businessType") Integer businessType) {
        QuestionRepositoryDropdownListDTO dropdownList = repositoryService.dropdownList(courseId, businessType, 0);
        return Result.success(dropdownList);
    }

    @ApiOperation("获取试卷下拉列表")
    @GetMapping(value = "/dropdown-list/owner")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result<QuestionRepositoryDropdownListDTO> dropdownListOwner(
            @PathVariable(value = "courseId") Long courseId, @PathVariable("businessType") Integer businessType) {
        QuestionRepositoryDropdownListDTO dropdownList = repositoryService.dropdownList(courseId, businessType, 1);
        return Result.success(dropdownList);
    }

    @ApiOperation("展示当前用户可以编辑的试题")
    @GetMapping(value = "/question")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result<PageDTO<QuestionListDTO>> questionList(
            @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(value = "keyWord", required = false) String keyWord,
            @RequestParam(value = "chapterId", required = false) Long chapterId,
            @RequestParam(value = "questionType", required = false) Integer questionType,
            @PathVariable(value = "courseId") Long courseId,
            @PathVariable(value = "businessType") Integer businessType) {
        PageDTO<QuestionListDTO> questionList = repositoryService.questionList(
                pageNum, pageSize, keyWord, courseId, chapterId, questionType, businessType,0);
        return Result.success(questionList);
    }

    @ApiOperation("展示当前用户可以编辑的试题")
    @GetMapping(value = "/questionOwner")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result<PageDTO<QuestionListDTO>> questionOwner(
            @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(value = "keyWord", required = false) String keyWord,
            @RequestParam(value = "chapterId", required = false) Long chapterId,
            @RequestParam(value = "questionType", required = false) Integer questionType,
            @PathVariable(value = "courseId") Long courseId,
            @PathVariable(value = "businessType") Integer businessType) {
        PageDTO<QuestionListDTO> questionList = repositoryService.questionList(
                pageNum, pageSize, keyWord, courseId, chapterId, questionType, businessType,  1);
        return Result.success(questionList);
    }

    @ApiOperation("添加新的试题")
    @PostMapping(value = "/question")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result<Long> addQuestion(
            @PathVariable("courseId") Long courseId,
            @PathVariable("businessType") Integer businessType,
            @RequestBody @Valid QuestionRepositoryAddQuestionParam questionRepositoryAddQuestionParam) {
        return Result.success(repositoryService.addQuestion(courseId, businessType, questionRepositoryAddQuestionParam));
    }

    @ApiOperation("展示预置题库题目信息")
    @GetMapping(value = "/preset")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<QuestionListDTO>> presetQuestionList(
            @RequestParam(value = "keyWord", required = false) String keyWord,
            @RequestParam(value = "chapterId", required = false) Long chapterId,
            @RequestParam(value = "courseId", required = false) Long courseDropdownId,
            @RequestParam(value = "questionType", required = false) Integer questionType,
            @PathVariable(value = "courseId") Long courseId,
            @PathVariable(value = "businessType") Integer businessType) {
        List<QuestionListDTO> questionList = repositoryService.presetQuestionList(keyWord, courseDropdownId, courseId, chapterId, questionType, businessType);
        return Result.success(questionList);
    }

    @ApiOperation("展示预制题目已选择题目情况")
    @GetMapping(value = "/preset/chosen")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<QuestionListDTO>> presetChosenList(
            @PathVariable(value = "courseId") Long courseId
    ) {
        List<QuestionListDTO> questionList = repositoryService.presetChosenList(courseId);
        return Result.success(questionList);
    }

    @ApiOperation("题目缓存新增题目")
    @PostMapping(value = "/preset/chosen")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<QuestionListDTO>> insertPresetChosen(
            @PathVariable(value = "courseId") Long courseId, @RequestBody IdsParam param
    ) {
        repositoryImportService.putCache(courseId, param.getIds());
        return Result.success();
    }

    @ApiOperation("题目缓存移除题目")
    @DeleteMapping(value = "/preset/chosen")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<QuestionListDTO>> deletePresetChosen(
            @PathVariable(value = "courseId") Long courseId, @RequestBody List<Long> ids
    ) {
        repositoryImportService.removeCache(courseId, ids);
        return Result.success();
    }

    @ApiOperation("从预置题库导入试题")
    @PostMapping(value = "/import-from-preset")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result importFromPreset(
            @PathVariable("courseId") Long courseId,
            @PathVariable("businessType") Integer businessType,
            @RequestBody List<Long> questionIds) {
        repositoryService.importFromPreset(courseId, businessType, questionIds);
        return Result.success();
    }

    @ApiOperation("下载导入模板")
    @GetMapping(value = "/model")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result getExcelModel(@PathVariable("businessType") Integer businessType, HttpServletResponse res, HttpServletRequest req) {
        repositoryService.getExcelModel(res, req, businessType);
        return Result.success();
    }

    @ApiOperation("从Excel导入试题")
    @PostMapping(value = "/import-from-excel")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result importFromExcel(
            @RequestParam(value = "file") MultipartFile file,
            @PathVariable("courseId") Long courseId,
            @PathVariable("businessType") Integer businessType) {
        repositoryService.importFromExcel(file, courseId, businessType);
        return Result.success();
    }

    @ApiOperation("从Excel导入随堂练习题")
    @PostMapping(value = "/import-from-excel/{chapterId}")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result importFromExcel(
            @RequestParam(value = "file") MultipartFile file,
            @PathVariable("courseId") Long courseId,
            @PathVariable("chapterId") Long chapterId,
            @PathVariable("businessType") Integer businessType) {
        repositoryService.importFromExcel(file, courseId, businessType, chapterId);
        return Result.success();
    }

    @ApiOperation("修改试题反显内容")
    @GetMapping(value = "/question/{questionId}")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result<QuestionListDTO> showUpdateQuestion(@PathVariable("courseId") Long courseId, @PathVariable("questionId") Long questionId) {
        return Result.success(repositoryService.showUpdateQuestion(courseId, questionId));
    }

    @ApiOperation("修改试题")
    @PutMapping(value = "/question/{questionId}")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result updateQuestion(
            @PathVariable("questionId") Long questionId,
            @PathVariable("courseId") Long courseId,
            @RequestBody @Valid QuestionRepositoryUpdateQuestionParam questionRepositoryUpdateQuestionParam
    ) {
        repositoryService.updateQuestion(courseId, questionId, questionRepositoryUpdateQuestionParam);
        return Result.success();
    }

    @ApiOperation("删除试题")
    @DeleteMapping(value = "/question")
    @PreAuthorize("@permissionValidator.isAdminOrTeacher()")
    public Result deleteQuestion(@RequestBody List<Long> questionIds, @PathVariable Long courseId) {
        repositoryService.deleteQuestion(courseId, questionIds);
        return Result.success();
    }

    @ApiOperation("按照题型查询题目列表")
    @GetMapping("/question-by-type")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<TypeQuestionListDTO>> listQuestionByType(
            @RequestParam(value = "chapterId", required = false) Long chapterId,
            @PathVariable(value = "courseId") Long courseId,
            @PathVariable(value = "businessType") Integer businessType) {
        return Result.success(repositoryService.listQuestionByType(chapterId, courseId, businessType));
    }

    @ApiOperation("获取章节下拉列表")
    @GetMapping("/chapter-list")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<ChapterBasicInfoDTO>> chapterList(@PathVariable("courseId") Long courseId) {
        return Result.success(repositoryService.chapterListOwner(Lists.newArrayList(courseId)));
    }

    @ApiOperation("课程-章节联动列表")
    @GetMapping("/course-chapter-list")
    @PreAuthorize("@permissionValidator.isTeacher()")
    public Result<List<ZtreeDTO>> courseChapterList() {
        return Result.success(repositoryService.getCourseChapterList());
    }
}
